﻿#import os
#import sys




# Настройка вывода ошибок в файл

# Определяется текущая директория

#__dir__ = os.path.dirname(os.path.abspath(__file__))
#path_error = os.path.join(__dir__, "so_test_error.log")

# Вывод ошибок перенаправляется в файл error.log в текущей директории

#sys.stderr = open(path_error, 'a')

from db import base as superbase
from db import relations as superrelations
from db import view as superview
from db import table as supertable
from db import aview as superaview
from db import atable as superatable
import cymysql



class base(superbase):
	"This class is a mysql connector"
	#print (self.__doc__)
	#beginning of class suite
	def __init__(self):
		super(base, self).__init__()
		self.driver=cymysql
		self.user='palo'
		self.passwd='palo'
		self.host='sa-serv10.tb.local'
		self.charset='utf8'
		self.base='palo'
		self.variable='%s'

	def open(self):
		"This function opens connection to base"
		#print (self.open.__doc__)
		#beginning of function suite
		self.conn = self.driver.connect(host=self.host, user=self.user, passwd=self.passwd, db=self.base, charset=self.charset)
		self.cursor=self.conn.cursor()
		return

	def execute_in_cycle(self, string, row=None, lim=0):
		"This function executes statement against the base optional for row of values"
		#beginning of function suite
		if not row:
			self.cursor.execute(string)
		else:
			self.cursor.execute(string, [row])
		if lim==0:
			result=self.cursor.fetchall()
		else:
			result=self.cursor.fetchmany(lim)
		#end of function suite
		#Функция возвращает результат запроса
		return result

	def execute_many_in_cycle(self, string, rows):
		"This function executes a statement for rows of values"
		#beginning of function suite
		#Выполняется запрос
		self.cursor.executemany(string, rows)
		result=self.cursor.fetchall()
		#end of function suite
		#Функция возвращает результат запроса
		return result

	def commit_in_cycle(self, string):
		"This function executes statement against the base and commits it"
		#beginning of function suite
		self.cursor.execute(string)
		#end of function suite
		return

	def execute(self, string, row=None, lim=0):
		"This function connects to base and executes a statement optional for row of values"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос в зависимости от наличия аргументов
		if not row:
			self.cursor.execute(string)
		else:
			self.cursor.execute(string, row)
		if lim==0:
			result=self.cursor.fetchall()
		else:
			result=self.cursor.fetchmany(lim)
		#Выполняется отключение от базы данных
		self.disconnect()
		#end of function suite
		#Функция возвращает результат запроса
		return result

	def generate(self, string, row=None, lim=1000):
		"This function connects to base and executes a statement optional for row of values"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос в зависимости от наличия аргументов
		if not row:
			self.cursor.execute(string)
		else:
			self.cursor.execute(string, row)
		while True:
			results=self.cursor.fetchmany(lim)
			if results==[]: 
				self.disconnect()
				break
			for result in results:
				yield result
		#end of function suite
		#Функция возвращает генератор результатов запроса

	def iterate(self, string, row=None, start=None, stop=None, step=None):
		"This function connects to base and executes a statement optional for a row of values"
		#beginning of function suite
		#end of function suite
		#Функция возвращает итератор результатов запроса
		return islice(self.generate(string, row), start, stop, step)

	def execute_many(self, string, rows):
		"This function connects to base and executes a statement for rows of values"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос
		self.cursor.executemany(string, rows)
		result=self.cursor.fetchall()
		#Выполняется отключение от базы данных
		self.disconnect()
		#end of function suite
		#Функция возвращает результат запроса
		return result

	def commit(self, string):
		"This function connects to base, executes a statement and commits it"
		#beginning of function suite
		#Выполняется подключение к базе данных
		self.connect()
		#Выполняется запрос
		self.cursor.execute(string)
		#Выполняется отключение от базы данных
		self.disconnect()
		#end of function suite
		return

	#end of class base suite

class relations(superrelations):
	"This class counts and select records for relations"
	#beginning of class suite
	#print (self.__doc__)
	#Инициализация:
	def __init__(self):
		super(relations, self).__init__()
		self.base=base()
#		self.variable='%s'

#Заменяется родительская функция
	def catalogue(self, type):
		return 'INFORMATION_SCHEMA.'+type.upper()

	#Заменяется родительская функция
	def field(self, type):
		return 'TABLE_NAME'

		def condition(self, type, word):
			'Function returns base specific condition for table/view catalogue'
			if word.lower()=='where':
				result=' '+'WHERE'+' '+'TABLE_SCHEMA='+"'"+self.base.base+"'"
			elif word.lower()=='and':
				result=' '+'AND'+' '+'TABLE_SCHEMA='+"'"+self.base.base+"'"
			return result

	#Заменяется родительская функция
	def type(self,type):
		'Function returns base specific type sign'
		dict={'t':'TABLES','v':'VIEWS'}
		return dict[type]

	#end of class relations suite

class view(superview):
	"This class is a manipulater for views"
	#beginning of class suite
	#print (self.__doc__)
	#Инициализация:
	def __init__(self):
		self.base=base()
		self.relations=relations()
		self.case=False

	def SqlCreate(self, name, fields, query, param):
		"Function returns sql string for the view create query"
		return "CREATE "+param+" VIEW "+self.SqlCase(name)+" AS "+query

	#end of class view suite

class table(supertable):
	"This class is a manipulater for views"
	#beginning of class suite
	#print (self.__doc__)
	#Инициализация:
	def __init__(self):
		super(table, self).__init__()
		self.base=base()
		self.relations=relations()
		self.case=False
		self.seq=False

	def SqlCreateTab(self, param, name, fields, primary, comment):
		"Function returns sql string for the view create query"
		result='CREATE'+' '+param+' '+'TABLE'+' '+self.SqlCase(name)+' '+self.newline
		result+='('+self.newline
		for row in fields:
			if row[0].lower()==primary.lower():
				result+=self.SqlCase(row[0])+' '+self.SqlCase(row[1])+' '+self.SqlCase(row[2])+' '+'AUTO_INCREMENT'+','+self.newline
			else:
				result+=self.SqlCase(row[0])+' '+self.SqlCase(row[1])+' '+self.SqlCase(row[2])+','+self.newline
		if primary!='':
			result+='PRIMARY KEY ('+self.SqlCase(primary)+')'
		else:
			result=result[:-2]
		result+=self.newline+')'
		result+=self.tab_create_extra(name, comment)
		return result

	def seq_drop_extra(self):
		return ' '+'CASCADE'

	#end of class table suite

class aview(superaview):
	"This class is a manipulater for a view"
	#beginning of class suite
	#print (self.__doc__)
	def __init__(self):
		super(aview, self).__init__()
		self.view=view()

	#end of class view suite

class atable(superatable):
	"This class is a manipulator for a table"
	#beginning of class suite
	#print (self.__doc__)
	def __init__(self):
		super(atable, self).__init__()
		self.table=table()

	#end of class atable suite

#Вывод ошибок возвращается "в исходное положение"

#sys.stderr.close()
#sys.stderr = sys.__stderr__